﻿ 
<!doctype html>
<html dir="ltr" lang="zh-CN">
  <head>
    <meta charset="utf-8"/>
    <meta http-equiv="X-UA-Compatible" content="IE=8">
    <style type="text/css">
      .drag {width:100px;height:100px;z-index:200;}
      #drag1 {background:red}
      #drag2 {background:#E8D098;}
      #drag3 {background:#fff;}
      #drag4 {background:#E8FFE8;margin-right:2px;margin-left:10px;}
      #drag5 {background:#ff0;}
      #drag6 {background:#66c;}
      #drag7 {background:#FBFBEA;}
      #drag8 {background:#E8E8FF;}
      #drag9 {background:#00B271;}
      #drag10 {background:#DDF3FF;}
      .handle {width:80px;height:20px;background:aqua;}
      #parent {width:300px;height:300px;background:blue;}
    </style>
    
    <script type="text/javascript">
      //辅助函数1
      
      var getCoords = function(el){
        var box = el.getBoundingClientRect(),   //获取页面元素的位置
        doc = el.ownerDocument,    //可返回某元素的根元素
        body = doc.body,  
        html = doc.documentElement,
        clientTop = html.clientTop || body.clientTop || 0,  //得到元素上边距   双竖线.逻辑运算符 从左到右返回一个值  clientTop :可见区域宽
        clientLeft = html.clientLeft || body.clientLeft || 0, //得到远素右边距
        top  = box.top  + (self.pageYOffset || html.scrollTop  ||  body.scrollTop ) - clientTop,
        left = box.left + (self.pageXOffset || html.scrollLeft ||  body.scrollLeft) - clientLeft
        return { 'top': top, 'left': left };
      };
      //辅助函数2
      var getStyle = function(el, style){  //获取样式
        if(!+"\v1"){
          style = style.replace(/\-(\w)/g, function(all, letter){
            return letter.toUpperCase();
          });
          var value = el.currentStyle[style];
          (value == "auto")&&(value = "0px" );
          return value;
        }else{
          return document.defaultView.getComputedStyle(el, null).getPropertyValue(style)    //当你无法确定元素的样式在哪里被定义，或元素同时被内联样式和CSS规则定义又不能确定哪一处定义是最优先级的，这时你需要获取其最终呈现的样式
                                                                                            // 这是w3c标准方法，取得元素的样式信息，因为有些样式是在外部css文件定义的，所以用ele.style是取不到的 如果是ie,可以用 ele.currentStyle["name"] 
        }
      }
      //============================
      var Drag = function(id){
        var el = document.getElementById(id),  //得到元素
        isQuirk = document.documentMode ? document.documentMode == 5 : document.compatMode && document.compatMode != "CSS1Compat", //回传一个数值对应目前页面的文件兼容性模式，举例来说，若网页指定为支持IE8模式，documentMode便会回传值"8"。
        options  = arguments[1] || {}, //arguments[n] 请求返回的第N个参数
        container = options.container || document.documentElement,  //指定元素
        limit = options.limit, //是否限定拖动范围
        lockX = options.lockX, //是否左右移动
        lockY = options.lockY, //是否锁定上下移动
        ghosting = options.ghosting, //是否只拖动影子
        handle = options.handle, //手柄的类名，当设置了此参数后，只允许用手柄拖动元素
        revert = options.revert, //是否弹回原位
        scroll = options.scroll, //是否随滚动条移动
        coords =  options.coords, //拖动时在手柄或影子元素上显示元素的坐标
        onStart =  options.onStart || function(){}, //拖动开始时执行
        onDrag =  options.onDrag || function(){}, //拖动中执行
        onEnd =  options.onEnd || function(){} , //拖动结束后执行
        marginLeft = parseFloat(getStyle(el,"margin-left")),//右距离
        marginRight = parseFloat(getStyle(el,"margin-right")),//右距离
        marginTop =  parseFloat(getStyle(el,"margin-top")), //上距离
        marginBottom = parseFloat(getStyle(el,"margin-bottom")),//下距离
        cls,
        _handle, //手柄内容
        _ghost,  //影子内容
        _top,  //上
        _left, //右
        _html; //内容
        el.lockX = getCoords(el).left; 
        alert( el.lockX)
        el.lockY = getCoords(el).top;
        el.style.position = "absolute"; //设为飘浮层
        if(handle){
          cls = new RegExp("(^|\\s)" + handle + "(\\s|$)");
          for(var i=0,l=el.childNodes.length;i<l;i++){
            var child = el.childNodes[i];
            if(child.nodeType == 1 && cls.test(child.className)){
              _handle = child;
              break;
            }
          }
        }
        _html = (_handle || el).innerHTML;
        var dragstart = function(e){   //开始移动
          e = e || window.event;
          el.offset_x = e.clientX - el.offsetLeft;
          el.offset_y = e.clientY - el.offsetTop;
          document.onmouseup = dragend;
          document.onmousemove = drag;
          if(ghosting){
            _ghost = el.cloneNode(false);
            el.parentNode.insertBefore(_ghost,el.nextSibling);
            if(_handle){
              _handle = _handle.cloneNode(false);
              _ghost.appendChild(_handle);
            }
              !+"\v1"? _ghost.style.filter = "alpha(opacity=50)" : _ghost.style.opacity = 0.5;
          }
          (_ghost || el).style.zIndex = ++Drag.z;
          onStart();//执行移动前func
          return false;
        }
        var drag = function(e) { //移动中
          e = e || window.event;
          el.style.cursor = "pointer";
            !+"\v1"? document.selection.empty() : window.getSelection().removeAllRanges();
          _left = e.clientX - el.offset_x ;
          _top = e.clientY - el.offset_y;
          if(scroll){
            var doc = isQuirk ? document.body : document.documentElement;
            doc = options.container || doc;
            options.container && (options.container.style.overflow = "auto");
            var a = getCoords(el).left + el.offsetWidth;
            var b = doc.clientWidth;
            if (a > b){
              doc.scrollLeft = a - b;
            }
            var c = getCoords(el).top + el.offsetHeight;
            var d = doc.clientHeight;
            if (c > d){
              doc.scrollTop = c - d;
            }
          }
          if(limit){
            var _right = _left + el.offsetWidth ,
            _bottom = _top + el.offsetHeight,
            _cCoords = getCoords(container),
            _cLeft = _cCoords.left,
            _cTop = _cCoords.top,
            _cRight = _cLeft + container.clientWidth,
            _cBottom = _cTop + container.clientHeight;
            _left = Math.max(_left, _cLeft);
            _top = Math.max(_top, _cTop);
            if(_right > _cRight){
              _left = _cRight - el.offsetWidth - marginLeft - marginRight;
            }
            if(_bottom > _cBottom){
              _top = _cBottom - el.offsetHeight  - marginTop - marginBottom;
            }
          }
          lockX && ( _left = el.lockX);
          lockY && ( _top = el.lockY);
          (_ghost || el).style.left = _left + "px";
          (_ghost || el).style.top = _top  + "px";
          coords && ((_handle || _ghost || el).innerHTML = _left + " x " + _top);
          onDrag(); //执行移动中func
        }

        var dragend = function(){ //移动结束
          document.onmouseup = null;
          document.onmousemove = null;
          _ghost && el.parentNode.removeChild(_ghost);
          el.style.left = _left + "px";
          el.style.top = _top +"px";
          (_handle || el).innerHTML = _html;
          if(revert){
            el.style.left = el.lockX   + "px";
            el.style.top = el.lockY  + "px";
          }
          onEnd();//执行移动结束func
        }
        Drag.z = 999;
        (_handle || el).onmousedown = dragstart;
      }
      window.onload = function(){  //载入
        var cache  = [];
        var _  = function(id){
          return cache[id] || (cache[id] = document.getElementById(id))
        }
        var p = _("parent");
       // new Drag("drag1",{coords:true,revert:true});
        new Drag("drag2",{coords:true,container:p,limit:true,lockX:true});
//        new Drag("drag3",{coords:true,coords:true,container:p,limit:true,lockY:true});
//        new Drag("drag4",{coords:true,container:p,limit:true,handle:"handle"});
//        new Drag("drag5",{coords:true,scroll:true});
//        new Drag("drag6",{coords:true,ghosting:true,limit:true,handle:"handle"})
//        new Drag("drag7",{coords:false,handle:"handle"});
//        new Drag("drag8",{coords:true,onStart:function(){_("drag8").innerHTML= "拖动开始"}});
//        new Drag("drag9",{onStart:function(){_("drag9").innerHTML= "拖动中"}});
//        new Drag("drag10",{coords:false,ghosting:true,onEnd:function(){_("drag10").innerHTML= "拖动结束"}});
      }
          var value = "";
          (value == "auto")&&(value = "0px" );
          alert(value);
    </script>
    <title>拖动</title>
  </head>
  <body id="body">
    <p>拖动时可能被选中的文本……………………</p>
    <div id="parent">
    <!--  <div id="drag1" class="drag">drag1测试revert参数</div>-->
      <div id="drag2" class="drag">drag2测试锁定X轴</div>
      <div id="drag3" class="drag">drag3测试锁定Y轴</div>
      <div id="drag4" class="drag"><div class="handle" >handle</div>drag4测试修正margin</div>
      <div id="drag5" class="drag">drag5测试scroll参数</div>
      <div id="drag6" class="drag">
        <div class="handle" >drag6</div>
        <img src="http://images.cnblogs.com/cnblogs_com/rubylouvre/202906/o_tear.gif" />
        <div>测试影子拖动</div>
      </div>
      <div id="drag7" class="drag"><div class="handle" >handle</div>drag7测试关闭显示坐标</div>
      <div id="drag8" class="drag">drag8测试onStart</div>
      <div id="drag9" class="drag">drag9测试onDrag</div>
      <div id="drag10" class="drag"><div class="handle" >handle</div>drag10测试onEnd</div>
    </div>
  </body>
</html>
